package org.lanplay.server.pages;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.ListMultipleChoice;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PropertyListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.util.SetModel;
import org.lanplay.server.LanPlaySession;
import org.lanplay.server.dao.GameDao;
import org.lanplay.server.dao.GameReferenceDao;
import org.lanplay.server.entitymodel.EntityModelFactory;
import org.lanplay.server.model.Game;
import org.lanplay.server.model.GameModification;
import org.lanplay.server.model.MatchRequest;
import org.lanplay.server.model.User;

import com.google.inject.Inject;

public class MatchRequestsPage extends TransactionAwarePage {
	private static final long serialVersionUID = 1L;

	@Inject
	private GameDao gameDao;

	@Inject
	private GameReferenceDao gameRefDao;

	@Inject
	private EntityModelFactory modelFactory;

	public MatchRequestsPage() {
		add(new BookmarkablePageLink<WebPage>("linkToMain", WelcomePage.class));
		add(new FeedbackPanel("feedback"));

		final LoadableDetachableModel<List<MatchRequest>> matchRequests = new LoadableDetachableModel<List<MatchRequest>>() {
			private static final long serialVersionUID = 1L;

			@Override
			protected List<MatchRequest> load() {
				return gameRefDao.getMatchRequestsForUserId((Long) getSession()
						.getAttribute(LanPlaySession.USER_ATTRIBUTE));
			}
		};
		add(new PropertyListView<MatchRequest>("pendingRequests", matchRequests) {
			private static final long serialVersionUID = 1L;

			@Override
			protected void populateItem(ListItem<MatchRequest> item) {
				item.add(new Label("game.name"));
				item.add(new Link<MatchRequest>("delete", item.getModel()) {
					private static final long serialVersionUID = 1L;

					@Override
					public void onClick() {
						gameRefDao.delete(getModelObject());
						matchRequests.detach();
					}
				});
			}
		});

		add(new RequestEditForm("requestEditForm", matchRequests));
	}

	private class RequestEditForm extends Form<MatchRequest> {
		private static final long serialVersionUID = 1L;
		private final IModel<List<MatchRequest>> matchRequests;
		private LoadableDetachableModel<List<Game>> gameChoicesModel;

		public RequestEditForm(String id,
				final IModel<List<MatchRequest>> matchRequests) {
			super(id, new CompoundPropertyModel<MatchRequest>(
					modelFactory.create(new MatchRequest())));
			this.matchRequests = matchRequests;

			gameChoicesModel = new LoadableDetachableModel<List<Game>>() {
				private static final long serialVersionUID = 1L;

				@Override
				protected List<Game> load() {
					Set<Game> gamesWithExistingMatchRequest = new HashSet<Game>();
					for (MatchRequest mr : matchRequests.getObject()) {
						gamesWithExistingMatchRequest.add(mr.getGame());
					}

					List<Game> gamesList = new LinkedList<Game>(
							gameDao.getGamesList());
					for (Iterator<Game> i = gamesList.iterator(); i.hasNext();) {
						if (gamesWithExistingMatchRequest.contains(i.next())) {
							i.remove();
						}
					}
					Collections.sort(gamesList, Game.CMP_GAME_NAME);
					return gamesList;
				}
			};
			add(new DropDownChoice<Game>("game", gameChoicesModel,
					new ChoiceRenderer<Game>("name")).setRequired(true));
			add(new ListMultipleChoice<GameModification>("mod",
					new SetModel<GameModification>(),
					new ArrayList<GameModification>()));
		}

		@Override
		protected void onSubmit() {
			MatchRequest matchRequest = getModelObject();
			if (matchRequest.getGame() != null) {
				matchRequest.setUser(new User((Long) getSession().getAttribute(
						LanPlaySession.USER_ATTRIBUTE)));
				gameRefDao.save(matchRequest);
				matchRequests.detach();
				gameChoicesModel.detach();
				setModel(new CompoundPropertyModel<MatchRequest>(
						modelFactory.create(new MatchRequest())));
			}
		}
	}
}
